package com.xnx3.j2ee.util;

import org.apache.commons.net.ftp.FTPClient;
import com.xnx3.FileUtil;
import com.xnx3.StringUtil;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
/**
 * FTP工具类
 * 需要使用  commons-net v3.3
* @author 周瑞宝,管雷鸣整理
* @date 2022/07/09
*/
public class FTPUtil {
    FTPClient ftpClient;
    private String hostname;   //ip或域名地址
    private int port = 21;     //端口默认21
    private String username;   //用户名
    private String password;   //密码
    
    private String currentPath;	//当前所在的FTP的目录，这个目录并不是实际的在服务器的目录，而是upload 中传入的filePath
    
    /**
    * 
    */
   public FTPUtil(String hostname, int port, String username, String password) {
       this.hostname = hostname;
       this.port = port;
       this.username = username;
       this.password = password;
       
       ftpClient = new FTPClient();
       currentPath = "-1";
   }

    /**
     * 上传
     *
     * @param hostname ip或域名地址
     * @param port  端口
     * @param username 用户名
     * @param password 密码
     * @param filePath 要将文件上传到ftp的哪个路径下,传入格式如 /web/root/ 
     * @param inputStream 要上传文件的输入流
     * @param fileName    设置上传之后的文件名 传入如:  a.html
     * @return
     */
      public boolean upload(String filePath, InputStream inputStream, String fileName) {
//          //如果第一个字符是 / ,那么将其去掉,因为框架要求的传入格式是 web/root/ ,前面不能带 /
//          if(filePath.indexOf("/") == 0) {
//              filePath = filePath.substring(1, filePath.length());
//          }
          
          int num = 0;	//尝试链接次数
          while(!ftpClient.isConnected() && num++ < 10) {
        	  //如果未建立链接，那么要打开链接
        	  if (connect(hostname, port, username, password)) {
        		  //打开成功
//        		  ConsoleUtil.debug("FTP打开链接");
        	  }else {
        		  ConsoleUtil.debug("FTP未能打开链接。当前第"+num+"次尝试");
        	  }
          }
          if(!ftpClient.isConnected()) {
        	  ConsoleUtil.error("FTP未能打开链接!放弃");
        	  return false;
          }
          
          	if(!this.currentPath.equals(filePath)) {
          		//跟上次不在一个目录下，要先进入这个目录
        	  	try {
        	  		String serverAbsPath = ftpClient.printWorkingDirectory()+filePath;
        	  		serverAbsPath = serverAbsPath.replaceAll("//", "/");	//去掉 //
//        	  		boolean makeDirectory = ftpClient.makeDirectory("a12");
//        	  		if(!makeDirectory) {
//        	  			ConsoleUtil.debug("创建目录失败。服务器中实际目录："+serverAbsPath);
//        	  		}
        	  		if (!ftpClient.changeWorkingDirectory(serverAbsPath)) {
        	  			ConsoleUtil.debug("FTP目录 "+filePath+" 进入返回false。可能是服务器权限有什么限定，多数情况下不影响文件上传。当然最终还要看文件是否传上去了。服务器中实际目录："+serverAbsPath);
	   				}else {
	   					ConsoleUtil.debug("进入FTP目录："+filePath+", 服务器中实际目录："+serverAbsPath);
	   				}
        	  		
        	  		this.currentPath = filePath;
        	  	} catch (IOException e) {
					e.printStackTrace();
				}
          }
          
          //上传
	      return storeFile(ftpClient, fileName, inputStream);
    }
    public boolean upload(String filePath, String text, String fileName) {
           InputStream fileInputStream = null;
           try {
               fileInputStream = StringUtil.stringToInputStream(text, FileUtil.UTF8);
           } catch (UnsupportedEncodingException e) {
               e.printStackTrace();
               ConsoleUtil.debug("stringToInputStream error.");
               return false;
           }
           return upload(filePath, fileInputStream, fileName);
     }
    /**
     * 断开连接
     *
     * @param ftpClient
     * @throws Exception
     */
    public static void disconnect(FTPClient ftpClient) {
        if (ftpClient.isConnected()) {
            try {
                ftpClient.disconnect();
                ConsoleUtil.info("已关闭连接");
            } catch (IOException e) {
                ConsoleUtil.info("没有关闭连接");
                e.printStackTrace();
            }
        }
    }
    /**
     * 测试是否能连接
     *
     * @param ftpClient
     * @param hostname  ip或域名地址
     * @param port      端口
     * @param username  用户名
     * @param password  密码
     * @return 返回真则能连接
     */
    public boolean connect(String hostname, int port, String username, String password) {
        boolean flag = false;
        try {
            //ftp初始化的一些参数
            ftpClient.connect(hostname, port);
            ftpClient.enterLocalPassiveMode();
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftpClient.setControlEncoding("UTF-8");
            if (ftpClient.login(username, password)) {
                ConsoleUtil.info("连接ftp成功");
                //ConsoleUtil.info(JSONArray.fromObject(ftpClient.listFiles()).toString());
                flag = true;
            } else {
                ConsoleUtil.info("连接ftp失败，可能用户名或密码错误");
                try {
                    disconnect(ftpClient);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } catch (IOException e) {
            ConsoleUtil.info("连接失败，可能ip或端口错误");
            e.printStackTrace();
        }
        return flag;
    }

    /**
     * 上传文件
     *
     * @param ftpClient
     * @param  path       全路径。如home/public/a.txt
     * @param fileInputStream 要上传的文件流
     * @return
     */
    public static boolean storeFile(FTPClient ftpClient, String path, InputStream fileInputStream) {
        boolean flag = false;
        try {
            if (ftpClient.storeFile(path, fileInputStream)) {
                flag = true;
            }
        } catch (IOException e) {
            ConsoleUtil.info("上传失败");
            e.printStackTrace();
        }
        return flag;
    }
   

    public static void main(String[] args) {
    	int port = 21;
//        String hostname = "ftp.cntd12n.99aiji.net";
//        String username = "zrb5517";
//        String password = "7YLQDG4SHMQ9";
    	
    	String hostname = "192.168.31.237";
        String username = "test";
        String password = "ewbHbiSMAKZmWw3L";
    	
        FTPUtil ftpTools = new FTPUtil(hostname, port, username, password);
//        boolean result = ftpTools.upload("/web/root/", "12345", "demo.html");
        boolean a = ftpTools.upload("/www/wwwroot/test/", "12345", "ha21.html");
        System.out.println(a);
	}
    
    
}
